namespace OpenComposite.Inbox.Attachments
{
	using System;
	using System.Windows.Forms;

	using OpenComposite.HumanActivity.Contracts;
	using System.IO;
	using OpenComposite.Inbox.Data;
	using System.Diagnostics;
	using OpenComposite.Inbox.Attachments;

	/// <summary>
	/// Summary description for frmAttachments.
	/// </summary>
	public class FormAttachments : System.Windows.Forms.Form
	{
		#region Initialization

		public FormAttachments(int userId, int? activityId, Guid workflowInstanceId)
		{
			if ( !this.DesignMode ) {
				this.UserId = userId;
				this.ActivityId = activityId;
				this.WorkflowInstanceId = workflowInstanceId;
			}
			InitializeComponent();

			dgvFiles.AutoGenerateColumns = false;
		}

		protected FormAttachments()
		{
			InitializeComponent();
		}

		#endregion Initialization

		#region Public Members

		#region Properties

		/// <summary>
		/// Gets or sets the activity id.
		/// </summary>
		/// <value>The activity id.</value>
		public int? ActivityId
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the user id.
		/// </summary>
		/// <value>The user id.</value>
		public int UserId
		{
			get;
			set;
		}

		/// <summary>
		/// Gets or sets the workflow instance id.
		/// </summary>
		/// <value>The workflow instance id.</value>
		public Guid WorkflowInstanceId
		{
			get;
			set;
		}

		#endregion Properties

		#region Methods

		public void ReloadView()
		{
			if ( this.DesignMode ) return;

			if ( this.IsHandleCreated ) {
				try {
					dgvFiles.DataSource =
						Global.DataAccess.GetAttachmentList(this.WorkflowInstanceId);
				} catch ( Exception ex ) {
					MessageBox.Show("Error while loading attachment list" + ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
		}

		#endregion Methods

		#endregion Public Members

		#region Protected Members

		#region Methods

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose(bool disposing)
		{
			if ( disposing ) {
				if ( components != null ) {
					components.Dispose();
				}
			}
			base.Dispose(disposing);
		}

		#endregion Methods

		#endregion Protected Members

		#region Private Members

		#region Fields

		private ContextMenuStrip cmAction;
		private System.ComponentModel.IContainer components;
		private DataGridView dgvFiles;
		private FolderBrowserDialog folderBrowserDialog;
		private System.Windows.Forms.OpenFileDialog openFileDialog;
		private ToolStripSeparator toolStripSeparator1;
		private ToolStripMenuItem tsmiAdd;
		private ToolStripMenuItem tsmiDownload;
		private ToolStripMenuItem tsmiEdit;
		private ToolStripMenuItem tsmiEditDesc;
		private ToolStripMenuItem tsmiRemove;
		private ToolStrip tsMain;
		private ToolStripButton tsbtnAddAttachment;
		private DataGridViewTextBoxColumn colFileName;
		private DataGridViewTextBoxColumn colFileDesc;
		private ToolStripSeparator toolStripSeparator2;

		#endregion Fields

		#region Event Handlers

		private void cmAction_Opened(object sender, EventArgs e)
		{
			this.cmAction.TopLevel = true;
		}

		private void frmAttachments_Load(object sender, System.EventArgs e)
		{
			if ( !this.DesignMode ) {
				ReloadView();
			}
		}

		private void tsmiAdd_Click(object sender, EventArgs e)
		{
			addNewAttachment();
		}

		private void tsmiDownload_Click(object sender, EventArgs e)
		{
			downloadAttachment();
		}

		private void tsmiEditDesc_Click(object sender, EventArgs e)
		{
			editDescription();
		}

		private void tsmiEdit_Click(object sender, EventArgs e)
		{
			editAttachment();
		}

		private void tsmiRemove_Click(object sender, EventArgs e)
		{
			removeAttachment();
		}

		private void tsbtnAddAttachment_Click(object sender, EventArgs e)
		{
			addNewAttachment();
		}

		private void dgvFiles_RowContextMenuStripNeeded(object sender, DataGridViewRowContextMenuStripNeededEventArgs e)
		{
			if ( e.RowIndex >= 0 ) {
				if ( !dgvFiles.Rows[e.RowIndex].Selected ) {
					dgvFiles.ClearSelection();
					dgvFiles.Rows[e.RowIndex].Selected = true;
				}
				e.ContextMenuStrip = cmAction;
			}
		}

		#endregion Event Handlers

		#region Methods

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormAttachments));
			this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
			this.dgvFiles = new System.Windows.Forms.DataGridView();
			this.colFileName = new System.Windows.Forms.DataGridViewTextBoxColumn();
			this.colFileDesc = new System.Windows.Forms.DataGridViewTextBoxColumn();
			this.cmAction = new System.Windows.Forms.ContextMenuStrip(this.components);
			this.tsmiDownload = new System.Windows.Forms.ToolStripMenuItem();
			this.tsmiEdit = new System.Windows.Forms.ToolStripMenuItem();
			this.tsmiEditDesc = new System.Windows.Forms.ToolStripMenuItem();
			this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
			this.tsmiAdd = new System.Windows.Forms.ToolStripMenuItem();
			this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
			this.tsmiRemove = new System.Windows.Forms.ToolStripMenuItem();
			this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
			this.tsMain = new System.Windows.Forms.ToolStrip();
			this.tsbtnAddAttachment = new System.Windows.Forms.ToolStripButton();
			( (System.ComponentModel.ISupportInitialize)( this.dgvFiles ) ).BeginInit();
			this.cmAction.SuspendLayout();
			this.tsMain.SuspendLayout();
			this.SuspendLayout();
			// 
			// openFileDialog
			// 
			this.openFileDialog.Filter = "All Files|*.*";
			this.openFileDialog.Title = "Add New Attachment";
			// 
			// dgvFiles
			// 
			this.dgvFiles.AllowUserToAddRows = false;
			this.dgvFiles.AllowUserToDeleteRows = false;
			this.dgvFiles.AllowUserToResizeRows = false;
			this.dgvFiles.BackgroundColor = System.Drawing.SystemColors.Window;
			this.dgvFiles.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
			this.dgvFiles.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None;
			this.dgvFiles.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
			this.dgvFiles.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.colFileName,
            this.colFileDesc});
			this.dgvFiles.Dock = System.Windows.Forms.DockStyle.Fill;
			this.dgvFiles.Location = new System.Drawing.Point(0, 25);
			this.dgvFiles.MultiSelect = false;
			this.dgvFiles.Name = "dgvFiles";
			this.dgvFiles.ReadOnly = true;
			this.dgvFiles.RowHeadersVisible = false;
			this.dgvFiles.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
			this.dgvFiles.Size = new System.Drawing.Size(520, 257);
			this.dgvFiles.TabIndex = 2;
			this.dgvFiles.RowContextMenuStripNeeded += new System.Windows.Forms.DataGridViewRowContextMenuStripNeededEventHandler(this.dgvFiles_RowContextMenuStripNeeded);
			// 
			// colFileName
			// 
			this.colFileName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells;
			this.colFileName.DataPropertyName = "FileName";
			this.colFileName.HeaderText = "File Name";
			this.colFileName.Name = "colFileName";
			this.colFileName.ReadOnly = true;
			this.colFileName.Width = 79;
			// 
			// colFileDesc
			// 
			this.colFileDesc.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
			this.colFileDesc.DataPropertyName = "Description";
			this.colFileDesc.HeaderText = "Description";
			this.colFileDesc.Name = "colFileDesc";
			this.colFileDesc.ReadOnly = true;
			// 
			// cmAction
			// 
			this.cmAction.AllowDrop = true;
			this.cmAction.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.tsmiDownload,
            this.tsmiEdit,
            this.tsmiEditDesc,
            this.toolStripSeparator1,
            this.tsmiAdd,
            this.toolStripSeparator2,
            this.tsmiRemove});
			this.cmAction.Name = "cmAction";
			this.cmAction.Size = new System.Drawing.Size(224, 126);
			// 
			// tsmiDownload
			// 
			this.tsmiDownload.Image = global::OpenComposite.Inbox.Properties.Resources.png_download;
			this.tsmiDownload.Name = "tsmiDownload";
			this.tsmiDownload.Size = new System.Drawing.Size(223, 22);
			this.tsmiDownload.Text = "Download Attachment...";
			this.tsmiDownload.Click += new System.EventHandler(this.tsmiDownload_Click);
			// 
			// tsmiEdit
			// 
			this.tsmiEdit.Name = "tsmiEdit";
			this.tsmiEdit.Size = new System.Drawing.Size(223, 22);
			this.tsmiEdit.Text = "Edit Attachment";
			this.tsmiEdit.Click += new System.EventHandler(this.tsmiEdit_Click);
			// 
			// tsmiEditDesc
			// 
			this.tsmiEditDesc.Name = "tsmiEditDesc";
			this.tsmiEditDesc.Size = new System.Drawing.Size(223, 22);
			this.tsmiEditDesc.Text = "Edit Attachment Description";
			this.tsmiEditDesc.Click += new System.EventHandler(this.tsmiEditDesc_Click);
			// 
			// toolStripSeparator1
			// 
			this.toolStripSeparator1.Name = "toolStripSeparator1";
			this.toolStripSeparator1.Size = new System.Drawing.Size(220, 6);
			// 
			// tsmiAdd
			// 
			this.tsmiAdd.Image = global::OpenComposite.Inbox.Properties.Resources.png_add_attachment;
			this.tsmiAdd.Name = "tsmiAdd";
			this.tsmiAdd.Size = new System.Drawing.Size(223, 22);
			this.tsmiAdd.Text = "Add Attachment...";
			this.tsmiAdd.Click += new System.EventHandler(this.tsmiAdd_Click);
			// 
			// toolStripSeparator2
			// 
			this.toolStripSeparator2.Name = "toolStripSeparator2";
			this.toolStripSeparator2.Size = new System.Drawing.Size(220, 6);
			// 
			// tsmiRemove
			// 
			this.tsmiRemove.Image = global::OpenComposite.Inbox.Properties.Resources.png_delete;
			this.tsmiRemove.Name = "tsmiRemove";
			this.tsmiRemove.Size = new System.Drawing.Size(223, 22);
			this.tsmiRemove.Text = "Remove Attachment";
			this.tsmiRemove.Click += new System.EventHandler(this.tsmiRemove_Click);
			// 
			// folderBrowserDialog
			// 
			this.folderBrowserDialog.Description = "Select Target Folder";
			// 
			// tsMain
			// 
			this.tsMain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.tsbtnAddAttachment});
			this.tsMain.Location = new System.Drawing.Point(0, 0);
			this.tsMain.Name = "tsMain";
			this.tsMain.Size = new System.Drawing.Size(520, 25);
			this.tsMain.TabIndex = 3;
			// 
			// tsbtnAddAttachment
			// 
			this.tsbtnAddAttachment.Image = global::OpenComposite.Inbox.Properties.Resources.png_add_attachment;
			this.tsbtnAddAttachment.ImageTransparentColor = System.Drawing.Color.Magenta;
			this.tsbtnAddAttachment.Name = "tsbtnAddAttachment";
			this.tsbtnAddAttachment.Size = new System.Drawing.Size(115, 22);
			this.tsbtnAddAttachment.Text = "Add Attachment";
			this.tsbtnAddAttachment.Click += new System.EventHandler(this.tsbtnAddAttachment_Click);
			// 
			// FormAttachments
			// 
			this.ClientSize = new System.Drawing.Size(520, 282);
			this.Controls.Add(this.dgvFiles);
			this.Controls.Add(this.tsMain);
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
			this.Icon = ( (System.Drawing.Icon)( resources.GetObject("$this.Icon") ) );
			this.MaximizeBox = false;
			this.MinimizeBox = false;
			this.Name = "FormAttachments";
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
			this.Text = "Attachments";
			this.Load += new System.EventHandler(this.frmAttachments_Load);
			( (System.ComponentModel.ISupportInitialize)( this.dgvFiles ) ).EndInit();
			this.cmAction.ResumeLayout(false);
			this.tsMain.ResumeLayout(false);
			this.tsMain.PerformLayout();
			this.ResumeLayout(false);
			this.PerformLayout();

		}

		private void addNewAttachment()
		{
			DialogResult result = this.openFileDialog.ShowDialog(this);
			if ( result == DialogResult.OK ) {
				try {
					FileInfo fileinfo = new FileInfo(this.openFileDialog.FileName);
					if ( fileinfo.Length < 60000000L ) {
						byte[] filecontent = File.ReadAllBytes(fileinfo.FullName);
						FormAttachmentDesc descForm = new FormAttachmentDesc();
						descForm.AttachmentFileName = fileinfo.Name;
						descForm.ShowDialog(this);
						AttachmentItem data = new AttachmentItem(
							this.WorkflowInstanceId, this.ActivityId, this.UserId);
						data.Data = filecontent;
						data.Description = descForm.Description;
						data.FileName = fileinfo.Name;
						data.Name = Path.GetFileNameWithoutExtension(fileinfo.FullName);
						Global.DataAccess.SetAttachment(data);
					} else {
						MessageBox.Show("You cannot attach files larger than 55 Megabytes.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
					}
				} catch ( Exception ) {
					MessageBox.Show("Error attaching file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}

			}
			ReloadView();
		}

		private void downloadAttachment()
		{
			if ( this.dgvFiles.SelectedRows.Count <= 0 ) {
				MessageBox.Show(
					"No attachments selected.", this.Text,
					MessageBoxButtons.OK, MessageBoxIcon.Information);
			}
			DialogResult result = this.folderBrowserDialog.ShowDialog();
			if ( result == DialogResult.Cancel ) return;
			try {
				foreach ( DataGridViewRow item in this.dgvFiles.SelectedRows ) {
					AttachmentItem row = (AttachmentItem)item.DataBoundItem;
					int folderDocID = row.AttachmentId.Value;
					byte[] fileContent = Global.DataAccess.GetAttachmentData(folderDocID); ;

					DialogResult dresult;
					string filepath = Path.Combine(folderBrowserDialog.SelectedPath, row.FileName);
					if ( File.Exists(filepath) ) {
						dresult = MessageBox.Show(
							"File " + filepath + " already exists. Overwrite with new content?",
							"Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
					} else {
						dresult = DialogResult.Yes;
					}
					if ( dresult == DialogResult.Yes ) {
						using ( FileStream fs = new FileStream(filepath, FileMode.Create, FileAccess.Write) ) {
							fs.Write(fileContent, 0, fileContent.Length);
							fs.Close();
						}
					} else {
						MessageBox.Show(
							"File " + filepath + " not downloaded.",
							"Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
					}
				}
				MessageBox.Show(
					"Successfully downloaded file(s) to folder " + folderBrowserDialog.SelectedPath,
					"Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
			} catch ( Exception ex ) {
				MessageBox.Show(
					"Error downloading file(s): " + ex.Message, "Error",
					MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void editAttachment()
		{
			//int folderDocID = 0;
			bool _byException = false;
			frmSplash splashForm = null;
			try {
				if ( dgvFiles.SelectedRows.Count == 1 ) {
					DataGridViewRow item = this.dgvFiles.SelectedRows[0];
					AttachmentItem attachment = item.DataBoundItem as AttachmentItem;
					if ( attachment == null || !attachment.AttachmentId.HasValue ) return; // EXIT

					byte[] fileContent = Global.DataAccess.GetAttachmentData(
						attachment.AttachmentId.Value);
					string extension = Path.GetExtension(attachment.FileName);
					string tempPath = Path.GetTempFileName() + extension;
					splashForm = new frmSplash(tempPath);
					File.WriteAllBytes(tempPath, fileContent);

					Process p = new Process();
					p.StartInfo = new ProcessStartInfo(tempPath);
					p.StartInfo.UseShellExecute = true;
					p.Start();
					DialogResult result = splashForm.ShowDialog();
					if ( result == DialogResult.OK ) {
						FileInfo info = new FileInfo(tempPath);
						if ( info.Length < 60000000L ) {
							byte[] newFileContent = File.ReadAllBytes(tempPath);
							attachment.Data = newFileContent;
							attachment.LastModifiedById = Global.CurrentUser.UserID;
							Global.DataAccess.SetAttachment(attachment);
							MessageBox.Show(
								"The file " + attachment.FileName + " was sucessfully updated.", this.Text,
								MessageBoxButtons.OK, MessageBoxIcon.Information);
						} else {
							MessageBox.Show("You cannot attach files larger than 55 Megabytes.", "Error",
								MessageBoxButtons.OK, MessageBoxIcon.Error);
						}
					}
					try {
						File.Delete(tempPath);
					} catch ( Exception ) {
						MessageBox.Show("Could not remove temporary file " + tempPath +
							". Close external application and delete file manually.",
							"Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
					}
				} else {
					MessageBox.Show("You have to select exactly one file to edit.",
						"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			} catch ( System.ComponentModel.Win32Exception ) {
				MessageBox.Show("No application assigned to file extension.",
					"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				_byException = true;
			} catch ( Exception ) {
				MessageBox.Show("Error downloading file(s)",
					"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				_byException = true;
			} finally {
				if ( _byException ) {
				}
			}
		}

		private void editDescription()
		{
			if ( dgvFiles.SelectedRows.Count == 0 ) return;
			AttachmentItem item = dgvFiles.SelectedRows[0].DataBoundItem as AttachmentItem;
			if ( item != null ) {
				FormAttachmentDesc frmDesc = new FormAttachmentDesc()
				{
					AttachmentFileName = item.FileName,
					Description = item.Description
				};
				if ( frmDesc.ShowDialog() == DialogResult.OK ) {
					item.Description = frmDesc.Description;
					item.LastModifiedById = Global.CurrentUser.UserID;
					Global.DataAccess.SetAttachment(item);
				}
			}
		}

		private void init()
		{
		}

		private void removeAttachment()
		{
			if ( this.dgvFiles.SelectedRows.Count > 0 ) {
				try {
					foreach ( DataGridViewRow item in this.dgvFiles.SelectedRows ) {
						AttachmentItem ai = item.DataBoundItem as AttachmentItem;
						if ( ai != null && ai.AttachmentId > 0 ) {
							Global.DataAccess.DeleteAttachment(ai.AttachmentId.Value);
						}
					}
				} catch ( Exception ) {
					MessageBox.Show("Error removing attachment(s).", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			} else {
				MessageBox.Show("No items selected.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
			}
			ReloadView();
		}

		#endregion Methods


		#endregion Private Members
	}
}